package org.mv.mm.api;

import java.io.Serializable;
import java.util.*;

/**
 *
 * @author Martin
 */
public class Doc implements Serializable, IConnectible {

  private static Map<String, Doc> docNameMap = new HashMap<>(300);
  static final long serialVersionUID = 10120323L;

  public static Doc createDoc(String workName) {
    Doc newDoc = new Doc(workName);

    // Add it to the static map.
    if (!addToNameMap(newDoc)) {
      //TODO ? nebo nic?
      return null;
    }
    return newDoc;
  }

  /**
   * Return all instances of Doc.
   *
   * @return all documents
   */
  public static List<Doc> getDocs() {
    List<Doc> docs = new ArrayList<>(docNameMap.values());
    return docs;
  }

  public static void removeDoc(Doc docToDelete) {
    docNameMap.remove(docToDelete.workName);
  }

  /**
   * Returns the fragment map (used for serialization).
   *
   * @return the map of fragments
   */
  public static Map<String, Doc> getDocNameMap() {
    return docNameMap;
  }

  public static void setDocNameMap(Map<String, Doc> docNameMap) {
    Doc.docNameMap = docNameMap;
  }

  /**
   * Adds provided Doc instance to the static map under the workName as a key.
   *
   * @param document Doc to save into map
   * @return true if the id (workName) was unique and the Doc instance has been
   * saved into map
   */
  private static boolean addToNameMap(Doc document) {

    if (docNameMap.containsKey(document.workName)) {
      return false;
    } else {
      docNameMap.put(document.workName, document);
      return true;
    }

  }
  private String abbrev;
  private String title;
  private String workName;
  private String author;
  private String description;
  private Date publishDate;
  private String publishNotes;
  private List<Fragment> fragments = new ArrayList<>();

  /**
   * Private constructor.
   *
   * @param workName
   */
  private Doc(String workName) {
    this.workName = workName;
    this.abbrev = workName.substring(0, 1).toUpperCase();
  }

  public String getAbbrev() {
    return abbrev;
  }

  public void setAbbrev(String abbrev) {
    this.abbrev = abbrev;
  }

  public String getWorkName() {
    return workName;
  }

  public void setWorkName(String workName) {
    this.workName = workName;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getAuthor() {
    return author;
  }

  public void setAuthor(String author) {
    this.author = author;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public List<Fragment> getFragments() {
    return fragments;
  }

  /**
   * Get all the fragments, which are directly under the document and so they
   * have no parent fragment (for example main chapters of a book or paragraphs
   * of short story, which has no chapters).
   *
   * @return top level fragments (which have no parent fragments)
   */
  public List<Fragment> getFirstLevelFragments() {
    if (fragments != null) {
      List<Fragment> firstLevelFrags = new ArrayList<>();
      for (Fragment frag : fragments) {
        if (frag.getParentFragment() == null) {
          firstLevelFrags.add(frag);
        }
      }
      return firstLevelFrags;
    } else {
      return null;
    }
  }

  public void addFragment(Fragment frag) {
    fragments.add(frag);
  }

  public void removeFragment(Fragment frag) {
    fragments.remove(frag);
  }
}
